package cn.huhaoran.yaoyaolingxian.ui;

import cn.huhaoran.yaoyaolingxian.config.NewPageAndViewModel;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.ui.TextBrowseFolderListener;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import cn.huhaoran.yaoyaolingxian.util.YaoYaoLingXianUtils;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.huhaoran.yaoyaolingxian.icons.PluginIcons.pluginIcon;

public class GenerateCode extends JFrame {
    private JPanel contentPane;
    private JButton buttonOK;
    private JButton buttonCancel;
    private TextFieldWithBrowseButton generatePathButton;
    private JTable table1;
    private JTree tree1;
    public JTextField pageName;
    private JTextField pageNameCN;
    private TextFieldWithBrowseButton jsonPath;
    private TextFieldWithBrowseButton enumPath;
    private JComboBox enumName;
    private JCheckBox useV2CheckBox;
    private JCheckBox onWillAppearCheckBox;
    private JCheckBox onAppearCheckBox;
    private JCheckBox onWillShowCheckBox;
    private JCheckBox onShownCheckBox;
    private JCheckBox onWillHideCheckBox;
    private JCheckBox onHiddenCheckBox;
    private JCheckBox onWillDisappearCheckBox;
    private JCheckBox onDisappearCheckBox;
    private AnActionEvent e;
    private String targetPath;
    private VirtualFile filePath;
    private Map<String, List<String>> enumListMap;



    public GenerateCode(AnActionEvent e, VirtualFile filePath) {
        NewPageAndViewModel instance = NewPageAndViewModel.getInstance(e.getProject());
        // 获取屏幕尺寸
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        int height = ge.getDefaultScreenDevice().getDisplayMode().getHeight();
        int width = ge.getDefaultScreenDevice().getDisplayMode().getWidth();

        System.out.println("屏幕尺寸：宽度:"+width+" 高度:"+height);
        // 计算对话框在屏幕中心的位置
        int x = (width - 550) / 2;
        int y = (height - 650) / 2;
        // 设置对话框的位置
        this.setLocation(x, y);
        this.setTitle("遥遥领先，遥遥==....                                                                                    ....====>领先！");
        //setUndecorated(true);
        this.e = e;
        this.filePath = filePath;
        if (filePath == null) {
            Notifications.Bus.notify(new Notification("Print", "无法自动生成", "您没有选择任何文件或者目录！", NotificationType.ERROR), e.getProject());
            return;
        }
        if (filePath.isDirectory()) {
            targetPath = filePath.getPath();
        } else {
            // 如果选中的是文件，则取文件所在目录
            targetPath = filePath.getParent().getPath();
            this.filePath = filePath.getParent();
        }
        generatePathButton.setText(targetPath);
        String enumPath1 = instance.getEnumPath();
        String enumName1 = instance.getEnumName();
        enumPath.setText(enumPath1);
        jsonPath.setText(instance.getJsonPath());

        try {
            enumListMap = YaoYaoLingXianUtils.parseFileContent(enumPath1);
            enumListMap.keySet().forEach((item)->enumName.addItem(item));
            enumName.setSelectedItem(enumName1);
        } catch (IOException ex) {
            Notifications.Bus.notify(new Notification("Print", "出现错误",
                    "在解析枚举文件时发生错误："+ex.getMessage() , NotificationType.WARNING), e.getProject());
        }

        //setLocationRelativeTo(null);
        // 载入持久化对象NewPageAndViewModel的checkBoxMap属性里面存的是本类属性JCheckBox的text值，value是是否选中，遍历ceckBoxMap并通过反射设置JCheckBox的值
        HashMap<String, Boolean> checkBoxMap = instance.getCheckBoxMap();
        // 通过反射获取本类对象的所有类型为JCheckBox的属性，并遍历他们，通过判断他们的属性值text是否在checkBoxMap里，来设置他们的选中与否
        for (java.lang.reflect.Field field : this.getClass().getDeclaredFields()) {
            if (field.getType() == JCheckBox.class) {
                try {
                    JCheckBox checkBox = (JCheckBox) field.get(this);
                    if (checkBoxMap.containsKey(checkBox.getText())) {
                        checkBox.setSelected(checkBoxMap.get(checkBox.getText()));
                    }
                } catch (IllegalAccessException err) {
                    Notifications.Bus.notify(new Notification("Print", "出现错误",
                            "通过反射获取存储属性时发生了异常：" +err.getMessage(), NotificationType.INFORMATION), e.getProject());
                }
            }
        }


        pageName.requestFocus();
        setContentPane(contentPane);
        //setModal(false);
        //getRootPane().setDefaultButton(buttonOK);

        buttonOK.addActionListener(e1 -> onOK());
        buttonCancel.addActionListener(e12 -> onCancel());

        // 点击 X 时调用 onCancel()
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                onCancel();
            }
        });

        // 遇到 ESCAPE 时调用 onCancel()
        contentPane.registerKeyboardAction(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        // 存放路径弹框
        generatePathButton.addBrowseFolderListener("选择想要生成的文件存放的路径", "", e.getProject(), new FileChooserDescriptor(false, true, false, false, false, false));
        jsonPath.addBrowseFolderListener("选择JSON路由文件", "", e.getProject(), new FileChooserDescriptor(true, false, false, false, true, false));
        /*enumPath.addBrowseFolderListener("选择枚举配置文件", "", e.getProject(), new FileChooserDescriptor(true, false, false, false, true, false));*/
        // 添加选择枚举文件的监听事件
        FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(true, false, false, false, true, false);
        fileChooserDescriptor.setTitle("选择枚举配置文件");
        enumPath.addBrowseFolderListener(new TextBrowseFolderListener(fileChooserDescriptor) {
            @Override
            public void onFileChosen(@NotNull VirtualFile chosenFile) {
                String selectedFilePath = chosenFile.getPath();
                enumPath.setText(selectedFilePath);
                // 在这里添加选择文件后的处理逻辑
                System.out.println("Selected file: " + selectedFilePath);
                //String selectedFilePath = enumPath.getText(); // 获取选择的文件路径
                // 执行额外的操作，例如打印路径
                System.out.println("Selected file path: " + selectedFilePath);
                // 用psijava解析文件，获取该文件内所有枚举类的名字
                VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(selectedFilePath);
                String filePath = virtualFile.getPath();
                System.out.println(filePath);
                try {
                    enumListMap = YaoYaoLingXianUtils.parseFileContent(filePath);
                } catch (IOException e) {
                    YaoYaoLingXianUtils.showMessgerOnBalloon(enumPath, " 解析文件时发生错误！："+e.getMessage());
                }
                // 打印结果
                enumListMap.forEach((key, value) -> {
                    System.out.println("Enum Name: " + key);
                    System.out.println("Values: " + value);
                });
                enumListMap.keySet().forEach((item-> enumName.addItem(item)));
            }
        });


        pageName.addFocusListener(new FocusAdapter() {@Override public void focusGained(FocusEvent e) {if (pageName.getSelectedText() == null){pageName.selectAll();}}});

        pageNameCN.addFocusListener(new FocusAdapter() {@Override public void focusGained(FocusEvent e) {if (pageNameCN.getSelectedText() == null) {pageNameCN.selectAll();}}});


    }


    private void onOK() {
        //System.out.println("目标路径 = " + targetPath);
        // 要替换的字符串键值对
        HashMap<String, Object> templateCharacterMap = new HashMap<>();
        templateCharacterMap.put("filePath", generatePathButton.getText());// 生成路径
        templateCharacterMap.put("pageName", pageName.getText());// 英文页面名称
        templateCharacterMap.put("pageNameCN", pageNameCN.getText());// 中文页面名称
        String date = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now());
        templateCharacterMap.put("DATE", date);
        templateCharacterMap.put("jsonPath",jsonPath.getText());
        templateCharacterMap.put("enumPath",enumPath.getText());
        if(enumName.getSelectedItem() != null){
            templateCharacterMap.put("enumName", enumName.getSelectedItem().toString());
            List<String> strings = enumListMap.get(enumName.getSelectedItem().toString());
            templateCharacterMap.put("enumIndex", strings.get(0));
        }
        // 利用反射将所有JCheckBox属性的text属性值作为key，选中与否作为value，压入templateCharacterMap中
        for (java.lang.reflect.Field field : this.getClass().getDeclaredFields()) {
            if (field.getType() == JCheckBox.class) {
                try {
                    JCheckBox checkBox = (JCheckBox) field.get(this);
                    templateCharacterMap.put(checkBox.getText(), checkBox.isSelected());
                } catch (IllegalAccessException err) {
                    Notifications.Bus.notify(new Notification("Print", "出现错误",
                            "在将多选框压入模板栈时出现错误："+err.getMessage() , NotificationType.WARNING), e.getProject());
                }
            }
        }

    /*    System.out.println(templateCharacterMap);
        Notifications.Bus.notify(new Notification("Print", "调试输出",
               "项目路径：" + Objects.requireNonNull(e.getProject()).getBasePath() + "\n被选中的文件路径：" + targetPath, NotificationType.INFORMATION), e.getProject());*/
        // todo 运行表单检查 和 持久化UI设置
        checkAndPersistence();
        YaoYaoLingXianUtils.generatePageFile(e, templateCharacterMap, GenerateCode.class.getClassLoader());

        /*// 创建一个 ScheduledExecutorService
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        // 调度任务在1秒后执行
        // todo 生成后要更新目录文件
      *//*  scheduler.schedule(() -> {
            SynchronizeFileUtil.synchronizeCurrentFile(e.getProject(), filePath);
            Notifications.Bus.notify(new Notification("Print", "调试输出",
                    "任务调度器成功运行了" , NotificationType.INFORMATION), e.getProject());
        }, 2, TimeUnit.SECONDS);*//*
        // 关闭调度器
        scheduler.shutdown();*/
        dispose();
    }

    private boolean checkAndPersistence() {
        // 检查JFrame里面generatePathButton、pageName、pageNameCN text值是否为空，如果为空则高亮提醒
        if (generatePathButton.getText().isEmpty() || pageName.getText().isEmpty() || pageNameCN.getText().isEmpty()) {
            Notifications.Bus.notify(new Notification("Print", "警告",
                    "请填写完整信息后再生成", NotificationType.WARNING), e.getProject());
            return false;
        }
        // 持久化保存JCheckBox的状态
        // 获取NewPageAndViewModel对象的所有JCheckBox类型的属性，并将其转换城一个HashMap<String,Boolean>，其key是该属性的text值，value是该属性的选中状态
        HashMap<String, Boolean> checkBoxMap = new HashMap<>();
        for (java.lang.reflect.Field field : this.getClass().getDeclaredFields()) {
            if (field.getType().equals(JCheckBox.class)) {
                try {
                    JCheckBox jCheckBox = (JCheckBox) field.get(this);
                    checkBoxMap.put(jCheckBox.getText(), jCheckBox.isSelected());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        NewPageAndViewModel instance = NewPageAndViewModel.getInstance(e.getProject());
        instance.setCheckBoxMap(checkBoxMap);
        instance.setJsonPath(jsonPath.getText());
        instance.setEnumPath(enumPath.getText());
        instance.setEnumName(enumName.getSelectedItem().toString());
        return true;
    }

    private void onCancel() {
        // 必要时在此处添加您的代码
        dispose();
    }


}
